import { languageMap } from '@/locales/lang-lists';
import { antdTheme } from '@/theme';
import { ConfigProvider } from 'antd';
import { createContext, useCallback, useEffect, useState, type ReactNode } from 'react';
import { useTranslation } from 'react-i18next';

import type { Locale } from 'antd/lib/locale';
import dayjs from 'dayjs';

type ConfigProviderContextType = {
	lang: string;
	setLanguage?: (lang: string) => void;
};

export const ConfigProviderContext = createContext<ConfigProviderContextType | undefined>(
	undefined
);

type ConfigProviderProps = {
	children: ReactNode;
};

const defaultLang = 'zh-CN';

// 通过 `__POWERED_BY_QIANKUN__` 判断是否在微服务环境中
const isMicroApp = (window as any).__POWERED_BY_QIANKUN__;

export const AppConfigProvider: React.FC<ConfigProviderProps> = ({ children }) => {
	const { i18n } = useTranslation();
	const [locale, setLocale] = useState<Locale | undefined>(undefined);
	// 增加一个加载状态
	const [isLoading, setIsLoading] = useState(true);

	// 当语言变化时，动态加载 antd 和 dayjs 的 locale 文件
	const handleLanguageChange = useCallback(async (lang: string) => {
		const langConfig = languageMap.get(lang || defaultLang);
		try {
			const [antdLocale, dayjsLocale] = await Promise.all([
				langConfig?.antdImport(),
				langConfig?.dayjsImport()
			]);
			setLocale(antdLocale?.default);
			dayjs.locale(dayjsLocale?.default?.name);
		} catch (error) {
			console.error('Error loading language files:', error);
		} finally {
			// 加载完成后，设置加载状态为 false
			setIsLoading(false);
		}
	}, []);

	useEffect(() => {
		// 初始化时，根据 i18n.language 加载一次
		if (i18n.isInitialized && i18n.language) {
			handleLanguageChange(i18n.language);
		}

		i18n.on('languageChanged', handleLanguageChange);

		return () => {
			i18n.off('languageChanged', handleLanguageChange);
		};
	}, [i18n, handleLanguageChange]);

	/**
	 * @function renderProvider
	 * @description 根据是否为微应用环境，渲染不同的 Provider
	 * @returns {React.ReactNode} 渲染的 React 节点
	 */
	const renderProvider = () => {
		const providerContent = (
			<ConfigProvider locale={locale} theme={antdTheme}>
				{children}
			</ConfigProvider>
		);

		if (isMicroApp) {
			return providerContent;
		}

		const contextValue: ConfigProviderContextType = {
			lang: i18n.language || defaultLang,
			setLanguage: (lang: string) => i18n.changeLanguage(lang)
		};

		return (
			<ConfigProviderContext.Provider value={contextValue}>
				{providerContent}
			</ConfigProviderContext.Provider>
		);
	};

	return !isLoading ? renderProvider() : null;
};
